﻿using System;
using System.Collections.Generic;
using System.IO;
using EmployeeApp.DAL.Dal;
using EmployeeApp.DAL.Entities;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using EmployeeApp.Service.Dto.Employee;
using FluentNHibernate.Automapping;
using EmployeeApp.DAL.Models;

namespace EmployeeApp.Service
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "EmployeeService" in code, svc and config file together.
    // NOTE: In order to launch WCF Test Client for testing this service, please select EmployeeService.svc or EmployeeService.svc.cs at the Solution Explorer and start debugging.
    public class EmployeeService : IEmployeeService
    {
        public ISession session;
        ISessionFactory sessionFactory;
        public EmployeeService()
        {
            System.Configuration.AppSettingsReader appReader = new System.Configuration.AppSettingsReader();
            string connectionString = Convert.ToString(appReader.GetValue("connectionString", typeof(string)));
            string mappingScriptPath = AppDomain.CurrentDomain.BaseDirectory + "/db_mappings";
            if (!Directory.Exists(mappingScriptPath))
                Directory.CreateDirectory(mappingScriptPath);

            sessionFactory = Fluently.Configure()
                .Database(
                    MsSqlConfiguration.MsSql2008
                    .ConnectionString(@connectionString))
                    .Mappings(x=> x.AutoMappings.Add(AutoMap.AssemblyOf<Employee>().Where(t => t.Namespace.EndsWith("Entities"))).ExportTo(@mappingScriptPath))
					.ExposeConfiguration(BuildSchema) // ********** ใช้ครั้งแรกเท่านั้น (กรณียังไม่มี Table)
                    .BuildSessionFactory();
            session = sessionFactory.OpenSession();
        }
        private static void BuildSchema(Configuration config)
        {
            new SchemaExport(config).Create(false, true);
        }

        public ResponseDto<List<EmployeeDto>> GetAll(GetAllRequestDto getAllRequestDto)
        {
            ResponseDto<List<EmployeeDto>> result = new ResponseDto<List<EmployeeDto>>();
            try
            {
                EmployeeDAL obj = new EmployeeDAL(session);

                SearchCriteria search = null;
                if (getAllRequestDto != null)
                {
                    search = new SearchCriteria() { 
                        EmpId = getAllRequestDto.EmpId, 
                        Name = getAllRequestDto.Name, 
                        Sort = getAllRequestDto.Sort, 
                        SortType = getAllRequestDto.SortType, 
                        Status = getAllRequestDto.Status 
                    };
                }

                var emp = obj.GetAll(search);
                if (emp.Count > 0)
                {
                    result.Data = new List<EmployeeDto>();
                    foreach (var item in emp)
                    {
                        result.Data.Add(new EmployeeDto()
                        {
                            Id = item.Id,
                            Address = item.Address,
                            EmpId = item.EmpId,
                            JobTitle = item.JobTitle,
                            MarriedStatus = item.MarriedStatus,
                            Name = item.Name,
                            Status = item.Status,
                            Surname = item.Surname,
                            Title = item.Title,
                            BirthDate = item.BirthDate
                        });
                    }
                }
                result.Status = true;
            }
            catch (Exception ex)
            {
                result.Status = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }

        public ResponseDto<EmployeeDto> Add(EmployeeDto employeeDto)
        {
            ResponseDto<EmployeeDto> result = new ResponseDto<EmployeeDto>();
            using (session.BeginTransaction())
            {
                try
                {
                    EmployeeDAL obj = new EmployeeDAL(session);
                    obj.Add(new Employee()
                    {
                        Address = employeeDto.Address,
                        EmpId = employeeDto.EmpId,
                        JobTitle = employeeDto.JobTitle,
                        MarriedStatus = employeeDto.MarriedStatus,
                        Name = employeeDto.Name,
                        Status = employeeDto.Status,
                        Surname = employeeDto.Surname,
                        Title = employeeDto.Title,
                        BirthDate = employeeDto.BirthDate
                    });
                    session.Transaction.Commit();
                    result.Status = true;
                }
                catch (Exception ex)
                {
                    session.Transaction.Rollback();
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<EmployeeDto> Update(EmployeeDto employeeDto)
        {
            ResponseDto<EmployeeDto> result = new ResponseDto<EmployeeDto>();

            using (session.BeginTransaction())
            {
                try
                {
                    EmployeeDAL obj = new EmployeeDAL(session);

                    Employee emp = new Employee();
                    emp.Id = employeeDto.Id;
                    emp.EmpId = employeeDto.EmpId;
                    emp.Address = employeeDto.Address;
                    emp.JobTitle = employeeDto.JobTitle;
                    emp.MarriedStatus = employeeDto.MarriedStatus;
                    emp.Name = employeeDto.Name;
                    emp.Status = employeeDto.Status;
                    emp.Surname = employeeDto.Surname;
                    emp.Title = employeeDto.Title;
                    emp.BirthDate = employeeDto.BirthDate;
                    obj.Update(emp);
                    session.Transaction.Commit();
                    result.Status = true;

                }
                catch (Exception ex)
                {
                    session.Transaction.Rollback();
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<EmployeeDto> Delete(List<string> IdList)
        {
            ResponseDto<EmployeeDto> result = new ResponseDto<EmployeeDto>(); 
            using (session.BeginTransaction())
            {
                try
                {
                    EmployeeDAL obj = new EmployeeDAL(session);
                    obj.Delete(IdList);
                    session.Transaction.Commit();
                    result.Status = true;
                }
                catch (Exception ex)
                {
                    session.Transaction.Rollback();
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }


    }
}
